package com.navi.mould1.service.impl;

import com.navi.bean.common.ToolToolgLineFabCorrelation;
import com.navi.bean.in.ConditionBean;
import com.navi.bean.out.abnormal_time_monitoring.AbnormalTimeMonitoringDataBean;
import com.navi.bean.out.abnormal_time_monitoring.AbnormalTimeMonitoringGridOut;
import com.navi.bean.sql.SqlVo;
import com.navi.core.repository.NaviRepository;
import com.navi.mould1.reportUtils.LKingSortUtil;
import com.navi.mould1.service.IAbnormalTimeMonitoringService;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections.map.HashedMap;
import org.apache.commons.lang.StringUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import java.sql.Timestamp;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;
import static com.navi.bean.sql.SqlVo.jointInSql;
import static com.navi.core.util.JdbcUtils.mySql_QueryRunner_QueryListBySql;


@Slf4j
@Service
public class AbnormalTimeMonitoringServiceImpl implements IAbnormalTimeMonitoringService {

    @Autowired
    private NaviRepository dao;


    public List<AbnormalTimeMonitoringGridOut> getGridData(ConditionBean conditions) {
        final SqlVo sqlVo = new SqlVo();
        sqlVo.appendSql("SELECT");
        sqlVo.appendSql("fab_id_fk,");
        sqlVo.appendSql("line_id_fk,");
        sqlVo.appendSql("tool_id_fk,");
        sqlVo.appendSql("alarm_code,");
        sqlVo.appendSql("start_timestamp,");
        sqlVo.appendSql("end_timestamp");
        sqlVo.appendSql("FROM ret_tool_alt A");
        sqlVo.appendSql("WHERE 1=1");
        if (StringUtils.isNotEmpty(conditions.getFab_id())) sqlVo.appendSql("AND A.FAB_ID_FK in" + jointInSql(conditions.getFab_id()));
        if (StringUtils.isNotEmpty(conditions.getLine_id())) sqlVo.appendSql("AND A.LINE_ID_FK in" + jointInSql(conditions.getLine_id()));
        if (StringUtils.isNotEmpty(conditions.getToolg_id())) sqlVo.appendSql("AND A.TOOL_ID_FK in(select tool_id from bis_tool where root_tool_id in (select tool_id_fk from bis_tool_gr where toolg_id in " + jointInSql(conditions.getToolg_id()) + "))");
        if (StringUtils.isNotEmpty(conditions.getTool_id())) sqlVo.appendSql("AND A.TOOL_ID_FK in" + jointInSql(conditions.getTool_id()));
        if (StringUtils.isNotEmpty(conditions.getStart_time())) sqlVo.appendSqlAndAddParam("AND A.START_TIMESTAMP >= ? ", conditions.getStart_time());
        if (StringUtils.isNotEmpty(conditions.getEnd_time())) sqlVo.appendSqlAndAddParam("AND A.START_TIMESTAMP <= ? ", conditions.getEnd_time());
        sqlVo.appendSql("ORDER BY A.START_TIMESTAMP");

        List<AbnormalTimeMonitoringDataBean> dataBeanList = mySql_QueryRunner_QueryListBySql(sqlVo, AbnormalTimeMonitoringDataBean.class);


        List<ToolToolgLineFabCorrelation> toolToolgLineFabCorrelation_list = getTool_toolg_line_fab_correlation();   //查询设备、设备组、线别、厂别之间的关联关系，及中文描述
        dataBeanList.forEach(dataBean -> {
            List<ToolToolgLineFabCorrelation> toolCorrelation_list = toolToolgLineFabCorrelation_list.stream().filter(data -> dataBean.getTool_id_fk().equals(data.getTool_id_fk())).collect(Collectors.toList());
            dataBean.setFab_id(toolCorrelation_list.get(0).getFab_id());
            dataBean.setLine_id(toolCorrelation_list.get(0).getLine_id());
            dataBean.setToolg_id(toolCorrelation_list.get(0).getToolg_id());
            dataBean.setToolg_id_fk(toolCorrelation_list.get(0).getToolg_id_fk());
            dataBean.setTool_id(toolCorrelation_list.get(0).getTool_id());
        });

        Map<String, List<AbnormalTimeMonitoringDataBean>> dataBean_Map = new HashedMap();
        if ("FAB".equals(conditions.getGroup_by())) {
            dataBean_Map = dataBeanList.stream().filter(data -> data.getStart_timestamp() != null && data.getEnd_timestamp() != null).collect(Collectors.groupingBy(AbnormalTimeMonitoringDataBean::getFab_id_fk));
        }else if ("LINE".equals(conditions.getGroup_by())) {
            dataBean_Map = dataBeanList.stream().filter(data -> data.getStart_timestamp() != null && data.getEnd_timestamp() != null).collect(Collectors.groupingBy(AbnormalTimeMonitoringDataBean::getLine_id_fk));
        }else if ("TOOLG".equals(conditions.getGroup_by())) {
            dataBean_Map = dataBeanList.stream().filter(data -> data.getStart_timestamp() != null && data.getEnd_timestamp() != null).collect(Collectors.groupingBy(AbnormalTimeMonitoringDataBean::getToolg_id_fk));
        }else if ("TOOL".equals(conditions.getGroup_by())) {
            dataBean_Map = dataBeanList.stream().filter(data -> data.getStart_timestamp() != null && data.getEnd_timestamp() != null).collect(Collectors.groupingBy(AbnormalTimeMonitoringDataBean::getTool_id_fk));
        }

        //计算每个分组的报警时长
        List<AbnormalTimeMonitoringGridOut> gridOut_list = new ArrayList<>();
        dataBean_Map.forEach((toolIdFk, groupBy_list) -> {
            AbnormalTimeMonitoringGridOut gridOut = new AbnormalTimeMonitoringGridOut();
            BeanUtils.copyProperties(groupBy_list.get(0), gridOut);
            gridOut.setKeep_second(groupBy_list.stream()
                    .map(data -> {
                        if (Timestamp.valueOf(data.getEnd_timestamp()).getTime() > Timestamp.valueOf(conditions.getEnd_time()).getTime()) data.setEnd_timestamp(conditions.getEnd_time());
                        return data;
                    }).mapToLong(data -> (Timestamp.valueOf(data.getEnd_timestamp()).getTime() - Timestamp.valueOf(data.getStart_timestamp()).getTime()) / 1000).sum()
            );
            gridOut.setKeep_minute(Long.parseLong(String.valueOf(gridOut.getKeep_second() / 60)));
            if (!"0".equals(gridOut.getKeep_second())) gridOut_list.add(gridOut);
        });

        LKingSortUtil.sort(gridOut_list, new String[] { "keep_minute" }, new boolean[] { false });

        return gridOut_list;
    }


    /*** 查询设备、设备组、线别、厂别之间的关联关系，及中文描述 **/
    private List<ToolToolgLineFabCorrelation> getTool_toolg_line_fab_correlation() {
        final SqlVo sqlVo = new SqlVo();
        sqlVo.appendSql("SELECT");
        sqlVo.appendSql("A.TOOL_ID AS tool_id_fk,");
        sqlVo.appendSql("A.TOOL_DSC as tool_id,");
        sqlVo.appendSql("B.TOOLG_ID as toolg_id_fk,");
        sqlVo.appendSql("b_3.data_desc as toolg_id,");
        sqlVo.appendSql("A.BAY_ID as line_id_fk,");
        sqlVo.appendSql("b_2.data_desc as line_id,");
        sqlVo.appendSql("A.FAB_ID_FK as fab_id_fk,");
        sqlVo.appendSql("b_1.data_desc as fab_id");
        sqlVo.appendSql("FROM");
        sqlVo.appendSql("bis_tool A");
        sqlVo.appendSql("LEFT JOIN bis_tool_gr B ON A.ROOT_TOOL_ID = B.TOOL_ID_FK");
        sqlVo.appendSql("LEFT JOIN (select data_ext,data_desc from icim_jn.bis_data where data_cate = 'FBID') b_1 ON A.FAB_ID_FK = b_1.data_ext");
        sqlVo.appendSql("LEFT JOIN (select data_ext,data_desc from icim_jn.bis_data where data_cate = 'AREA') b_2 ON A.BAY_ID = b_2.data_ext");
        sqlVo.appendSql("LEFT JOIN (select data_ext,data_desc from icim_jn.bis_data where data_cate = 'TOLG') b_3 ON B.TOOLG_ID = b_3.data_ext");
        sqlVo.appendSql("ORDER BY A.TOOL_DSC");

        //List<ToolToolgLineFabCorrelation> tool_toolg_line_fab_list = dao.findBySQL(sqlVo.getSql());
        //List<ToolToolgLineFabCorrelation> tool_toolg_line_fab_list = LKingDao.queryListBySql(sqlVo, ToolToolgLineFabCorrelation.class);
        List<ToolToolgLineFabCorrelation> tool_toolg_line_fab_list = new ArrayList<>();
        List<Object[]> objList = dao.findBySQL(sqlVo.getSql());
        for (Object[] objects : objList) {
            ToolToolgLineFabCorrelation bean = new ToolToolgLineFabCorrelation();
            bean.setTool_id_fk(objects[0].toString());
            bean.setTool_id(objects[1].toString());
            bean.setToolg_id_fk(objects[2].toString());
            bean.setToolg_id(objects[3].toString());
            bean.setLine_id_fk(objects[4].toString());
            bean.setLine_id(objects[5].toString());
            bean.setFab_id_fk(objects[6].toString());
            bean.setFab_id(objects[7].toString());
            tool_toolg_line_fab_list.add(bean);
        }
        return tool_toolg_line_fab_list;
    }


}
